const TzLengthUnit = {
  MM: 0, // 毫米
  FEET_INCHES: 1, // 英尺英寸
  INCHES: 2, // 英寸
};

const TzInchesFormat = {
  FRACTIONAL: 0, // 分数
  DECIMAL: 1, // 小数
};

class TzLengthSetting {
  constructor() {}

  static get reg() {
    return /^(((([1-9]\d*)([ ]+|\x2d+))?([1-9]\d*)(\/)([1-9]\d*))|(([1-9]\d*\.?\d*)|([0]\.\d*)))((\x27(((([1-9]\d*)([ ]+|\x2d+))?([1-9]\d*)(\/)([1-9]\d*))|(([1-9]\d*\.?\d*)|([0]\.\d*)))(\x22))|(\x27|\x22))|(([1-9]\d*\.?\d*)|([0]\.\d*))/g;
  }

  // 正则限制输入的只有纯数字或英尺英寸
  static adjustInchesInput(value) {
    let _value = value + '';
    let patt = /[ 0-9\x2e\x2f\x27\x22\x2d‘’“”]*/g;
    let z = patt.exec(_value);
    let inches = '';
    if (z != null) {
      inches = z[0];
      inches = inches
        .replace('‘', "'")
        .replace('’', "'")
        .replace('“', '"')
        .replace('”', '"');
    }
    return inches;
  }

  // 格式化输入的值
  static formatValue(value) {
    let z = this.reg.exec(value);
    let inches = '';
    if (z != null) {
      inches = z[0];
    }
    return inches;
  }

  // 毫米转英制（参数：值, 是否不需要英尺部分, 分母[为1则分数部分四舍五入], 分数/小数, 小数保留位）
  static milliMeterToInchesFun(
    value,
    isNoneFeet = false,
    inchesPrecision = 64,
    inchesFormat = TzInchesFormat.FRACTIONAL,
    inchesDigit = 2
  ) {
    if (
      !/^[\d]+[\d]$/.test(value) &&
      !/^[\d]$/.test(value) &&
      !parseFloat(value) > 0
    ) {
      return '';
    }
    let inchesNumAll = ((value * 100) / 25.4 / 100).toFixed(2); // 1.计算所有的英寸及小数，避免JS计算的转换进制计算的误差，只取到小数两位
    let feetNum = parseInt(inchesNumAll / 12); // 2.计算英尺整数
    let inchesIntAll = parseInt(inchesNumAll); // 计算英寸整数
    let inchesNumInt = parseInt(inchesNumAll - feetNum * 12); // 3.计算剩余的英寸整数
    function formatFloat(decimals) {
      let formatDecimals = decimals.toFixed(2) * inchesPrecision;
      if (formatDecimals > 0 && formatDecimals < `${1 / inchesPrecision}`) {
        return `${1}/${inchesPrecision}`;
      }
      let numeratorInt = Math.round(formatDecimals);
      if (!numeratorInt) {
        return '';
      }
      if (numeratorInt === inchesPrecision) {
        return 1;
      }
      // 对分子分母进行约分
      let m = numeratorInt;
      let n = inchesPrecision;
      let a = m;
      let b = n;
      if (a >= b) {
        a = m;
        b = n;
      } else {
        a = n;
        b = m;
      }
      if (m !== 1 && n !== 1) {
        for (let i = b; i >= 2; i--) {
          if (m % i === 0 && n % i === 0) {
            m = m / i;
            n = n / i;
          }
        }
      }
      return `${m}/${n}`;
    }
    let inchesNumFloat = '';
    if (inchesFormat === TzInchesFormat.FRACTIONAL) {
      // 分数
      // 4.计算剩余的英寸小数，并转为分数（最大分母为32）
      inchesNumFloat = formatFloat(inchesNumAll - feetNum * 12 - inchesNumInt);
    } else if (inchesFormat === TzInchesFormat.DECIMAL) {
      // 小数
      inchesNumFloat = (inchesNumAll - feetNum * 12 - inchesNumInt).toFixed(
        inchesDigit
      );
    }
    let allIn = '';
    if (isNoneFeet) {
      // 限制只要英寸格式的值
      if (inchesPrecision === 1) {
        // 是否作分数的四舍五入
        inchesNumFloat =
          inchesNumAll - feetNum * 12 - inchesNumInt >= 0.5 ? 1 : '';
      }
      if (inchesNumFloat === 1) {
        inchesNumFloat = '';
        inchesIntAll = inchesIntAll + 1 || 1;
      }
      if (inchesNumFloat) {
        allIn = inchesNumFloat + '"';
        if (inchesIntAll) {
          allIn = inchesIntAll + ' ' + allIn;
        }
      } else if (inchesIntAll) {
        allIn = inchesIntAll + '"';
      }
    } else {
      // 未限制只要英寸格式的值
      if (inchesPrecision === 1) {
        // 是否作分数的四舍五入
        inchesNumFloat =
          inchesNumAll - feetNum * 12 - inchesNumInt >= 0.5 ? 1 : '';
      }
      if (inchesNumFloat === 1) {
        inchesNumFloat = '';
        if (inchesNumInt === 11) {
          inchesNumInt = '';
          feetNum = feetNum + 1;
        } else {
          inchesNumInt = inchesNumInt + 1 || 1;
        }
      }
      // 如果英尺小于3'，则转换为英寸
      if (feetNum && feetNum < 3) {
        inchesNumInt = inchesNumInt + feetNum * 12;
        feetNum = 0;
      }
      if (inchesNumFloat) {
        allIn = inchesNumFloat + '"';
        if (inchesNumInt) {
          allIn = inchesNumInt + ' ' + allIn;
          if (feetNum) {
            allIn = feetNum + "'" + allIn;
          }
        } else if (feetNum) {
          allIn = feetNum + "'" + allIn;
        }
      } else if (inchesNumInt) {
        allIn = inchesNumInt + '"';
        if (feetNum) {
          allIn = feetNum + "'" + allIn;
        }
      } else if (feetNum) {
        allIn = feetNum + "'";
      }
    }
    return allIn;
  }

  // 英制转毫米（参数：值，小数保留位）
  static inchesToMilliMeter(value, digit = 2) {
    value = this.formatValue(value);
    if (value === '0') {
      return 0;
    }
    if (!value || !this.reg.test(value)) {
      return '';
    }
    let feetNum = 0; // 英尺的整数部分
    let inchesNum = 0; // 英寸的整数部分
    let inchesNumScore = 0; // 英寸的小数部分
    let inchesNumScoreM = 0; // 英寸的小数部分的分母
    let inchesNumScoreZ = 0; // 英寸的小数部分的分子
    let mmNumAll = '';
    if (value.indexOf("'") > -1) {
      feetNum = value.substring(0, value.indexOf("'"));
      if (value.indexOf('"') > -1) {
        if (value.indexOf('/') > -1) {
          if (/\s/.test(value)) {
            inchesNum = value.substring(
              value.indexOf("'") + 1,
              value.indexOf(' ')
            );
            inchesNumScore = value.substring(
              value.indexOf(' ') + 1,
              value.indexOf('"')
            );
            inchesNumScoreZ = inchesNumScore.split('/')[0];
            inchesNumScoreM = inchesNumScore.split('/')[1];
          } else {
            inchesNumScore = value.substring(
              value.indexOf("'") + 1,
              value.indexOf('"')
            );
            inchesNumScoreZ = inchesNumScore.split('/')[0];
            inchesNumScoreM = inchesNumScore.split('/')[1];
          }
        } else {
          inchesNum = value.substring(
            value.indexOf("'") + 1,
            value.indexOf('"')
          );
        }
      }
    } else if (value.indexOf('"') > -1) {
      if (value.indexOf('/') > -1) {
        inchesNum = value.substring(0, value.indexOf(' '));
        inchesNumScore = value.substring(
          value.indexOf(' ') + 1,
          value.indexOf('"')
        );
        inchesNumScoreZ = inchesNumScore.split('/')[0];
        inchesNumScoreM = inchesNumScore.split('/')[1];
      } else {
        inchesNum = value.substring(0, value.indexOf('"'));
      }
    }
    if (feetNum) {
      mmNumAll = feetNum * 25.4 * 12;
      if (!isNaN(inchesNum)) {
        mmNumAll = mmNumAll + inchesNum * 25.4;
        if (inchesNumScoreZ && inchesNumScoreM) {
          mmNumAll = mmNumAll + (inchesNumScoreZ / inchesNumScoreM) * 25.4;
        }
      } else if (!isNaN(inchesNumScoreZ) && !isNaN(inchesNumScoreM)) {
        mmNumAll = mmNumAll + (inchesNumScoreZ / inchesNumScoreM) * 25.4;
      }
    } else if (!isNaN(inchesNum)) {
      mmNumAll = inchesNum * 25.4;
      if (inchesNumScoreZ && inchesNumScoreM) {
        mmNumAll = mmNumAll + (inchesNumScoreZ / inchesNumScoreM) * 25.4;
      }
    } else if (!isNaN(inchesNumScoreZ) && !isNaN(inchesNumScoreM)) {
      mmNumAll = (inchesNumScoreZ / inchesNumScoreM) * 25.4;
    }
    let digitPow = 1;
    if (digit) {
      digitPow = Math.pow(10, digit); // 取10的dright次方
    }
    return Math.round(mmNumAll * digitPow) / digitPow;
  }

  // 数据格式化为毫米
  static fixMilliMeter(value) {
    let _value = Number(value);
    if (!_value) {
      _value = this.inchesToMilliMeter(value);
    }
    return _value;
  }
}

export { TzLengthSetting, TzLengthUnit };
